package network;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.util.ArrayList;

import org.hibernate.Session;

import bdd.sql.server.hibernate.HibernateUtil;

import tools.ConfParser;

/**
 * Serveru TCP.
 * @author Guillaume Poças
 */
public class KrakenServer {
	
	//private static final int DEFAULT_PORT_NUMBER = 18000;
	//local
	//private static final String PATH_CONF_FILE = "C:\\Documents and Settings\\Guillaume\\workspace\\vsm_M2\\conf\\server.conf";
	//serv web
	//private static final String PATH_CONF_FILE = "C:\\Serveur Java\\server.conf";
	//serv ubuntu
	private static final String PATH_CONF_FILE = "/etc/kraken/server.conf";
	
	private static final String DEFAULT_PORT = "DEFAULT_PORT";
	
	private ArrayList<PrintWriter> tabClients;
	private int nbClients;
	private int port;
	private boolean serverOn;
	
	/**
	 * Constructeur.
	 * @param port_
	 */
	public KrakenServer(String port_){
		try{
			tabClients = new ArrayList<PrintWriter>(); // contiendra tous les flux de sortie vers les clients
			nbClients = 0;
			serverOn = true;
			
			ConfParser parser = new ConfParser();
			try {
				parser.parse(new File(PATH_CONF_FILE)); //Applet.Constant ?
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println(parser.getValue(DEFAULT_PORT));
			int default_port_number = Integer.valueOf(parser.getValue(DEFAULT_PORT));
			
			if(port_.equals(""))	port = default_port_number; //port 18000 par défaut
			else	port = new Integer(port_); //sinon premier argument

			@SuppressWarnings("resource")
			ServerSocket serverSocket = new ServerSocket(port); // ouverture d'un socket serveur sur port
		    printWelcome(port);
		    
		    Session session = HibernateUtil.getSession();
				    
		    while(serverOn){ // attente en boucle de connexion (bloquant sur serverSocket.accept)
		    	new KrakenThread(serverSocket.accept(),this, port); // un client se connecte, un nouveau thread client est lancé
		    }
	    }
	    catch(Exception e){
	    	e.printStackTrace();//
	    }
	}

	/**
	 * Informations sur le serveur.
	 * @param port
	 */
	public void printWelcome(Integer port){
		System.out.println("--------");
		System.out.println("Kraken");
		System.out.println("Projet Kraken M2 ISIM SIC 2014");
		System.out.println("Version 0.2 : 14/05/2013");
		System.out.println("--------");
		System.out.println("Demarre sur le port : " +port.toString());
		System.out.println("--------");
	}

	/**
	 * Envoi un message à tous les clients du serveur.
	 * @param message
	 * @param sLast
	 */
	synchronized public void sendAll(String message,String sLast){
		PrintWriter out;
		
		for(int i = 0; i < tabClients.size(); i++){ 
			out = (PrintWriter) tabClients.get(i);
			
			if(out != null){
				out.println(message+sLast);
				out.flush();
			}
		}
	}

	/**
	 * Supprime le client.
	 * @param i
	 */
	synchronized public void delClient(int i){
		nbClients--;
		
		if(tabClients.get(i) != null){
			tabClients.remove(i);
		}
	}
	
	public int getPort(){ return this.port; }
	
	public void setServerOnOff(boolean state){ this.serverOn = state; }

	/**
	 * Ajout un nouveau client.
	 * @param out
	 * @return
	 */
	synchronized public int addClient(PrintWriter out){
		nbClients++;
		tabClients.add(out);
		return tabClients.size()-1;
	}

	/**
	 * Le nombre de clients connectés.
	 * @return
	 */
	synchronized public int getNbClients(){
		return nbClients;
	}

}
